/////////////////////////////////////////////////////
// File Name: hash_lut_tb.v
// Author: zeping fan
// mail:   zpfan007@163.com
// Created Time: 2023年06月16日 星期五 16时20分40秒
/////////////////////////////////////////////////////
module hash_lut_tb();


reg             clk;
reg             rst_n;
reg             se_source;
reg     [47:0]  se_mac;
reg     [15:0]  se_portmap;
reg     [9:0]   se_hash;
reg             se_req;
reg             aging_req;

wire    [15:0]  se_result;
wire            se_ack;
wire            se_nak;
wire            aging_ack;

always #10 clk = ~clk;

initial begin
    $fsdbDumpfile("hash_lut.fsdb");
    $fsdbDumpvars(0,hash_lut_tb);
    $fsdbDumpMDA();

    clk = 1'b0;
    rst_n = 1'b0;
    se_source = 1'b1;
    se_mac = 48'b0;
    se_portmap = 16'b0;
    se_hash = 10'b0;
    se_req = 1'b0;
    aging_req = 1'b0;
    repeat(2) @(posedge clk);#0;
    rst_n = 1'b1;
    repeat(1030) @(posedge clk);#0;
//添加表项
    add_entry(48'ha0b1c2d3e4f5,16'h0002,40);
    add_entry(48'hb4d8c9821035,16'h0004,40);
    add_entry(48'h294758d0ad9f,16'h0008,40);
    repeat(5) @(posedge clk);#0;
//查找操作
    search(48'ha0b1c2d3e4f5,40);
    search(48'hb4d8c9821035,40);
    search(48'h294758d0ad9f,40);

    repeat(5) @(posedge clk);#0;


//老化操作
    aging;
    repeat(5) @(posedge clk);#0;
    aging;
    repeat(5) @(posedge clk);#0;
    add_entry(48'ha0b1c2d3e4f5,16'h0002,40);
    repeat(5) @(posedge clk);#0;
    aging;
    repeat(5) @(posedge clk);#0;
    aging;
    repeat(5) @(posedge clk);#0;
    search(48'ha0b1c2d3e4f5,40);
    search(48'hb4d8c9821035,40);

    #200;
    $finish;
end


//====================添加新表项===================
task add_entry;
    input   [47:0]  mac_addr;
    input   [15:0]  port;
    input   [9:0]   hash;

begin
    repeat(1)@(posedge clk);#0;
    se_source = 1'b1;
    se_req = 1'b1;
    se_mac[47:0] =  mac_addr[47:0];
    se_portmap[15:0] = port[15:0];
    se_hash[9:0] = hash[9:0];
    while(!(se_ack | se_nak))
        repeat(1)@(posedge clk);#0;
    se_req = 1'b0;
    se_source = 1'b0;
end
endtask

//====================查找操作====================
task search;
    input   [47:0]  mac_addr;
    input   [9:0]   hash;

begin
    repeat(1)@(posedge clk);#0;
    se_source = 1'b0;
    se_req = 1'b1;
    se_mac[47:0] = mac_addr[47:0];
    se_hash[9:0] = hash[9:0];
    while(!(se_ack | se_nak))
        repeat(1)@(posedge clk);#0;
    se_req = 1'b0;
end
endtask


//====================老化操作====================
task aging;
begin
    repeat(1)@(posedge clk);#0;
    aging_req <= 1'b1;
    while(!aging_ack)
        repeat(1)@(posedge clk);#0;
    aging_req <= 1'b0;
end
endtask




hash_lut_v1#(
    .TTL_NUM(2'd3)
)    x_hash_lut(
.clk(clk),
.rst_n(rst_n),
.se_source(se_source),
.se_mac(se_mac),
.se_portmap(se_portmap),
.se_hash(se_hash),
.se_req(se_req),
.se_ack(se_ack),
.se_nak(se_nak),
.se_result(se_result),
.aging_req(aging_req),
.aging_ack(aging_ack)
);


endmodule
